package main

// Defer 后进先出
func Defer() {
	defer func() {
		println("first defer")
	}()

	defer func() {
		println("second defer")
	}()
}

// 运行时确定 => 输出1
// 这个j是引用的，defer里面的j和外部一样
func DeferClosure() {
	j := 0
	defer func() {
		println(j)
	}()
	j = 1
}

// 里面的j是被赋值了的, defer定义的时候就传入赋值了，后面j被改动是无影响的 => 输出0
// 建议用这种方法
func DeferClosureV1() {
	j := 0
	defer func(j int) {
		println(j)
	}(j)
	j = 1
}

// 没有被改变 => 输出0
func DeferReture() int {
	a := 0
	defer func() {
		a = 1
	}()
	return a
}

// a被defer中修改 => 输出1
// 注意: 唯一一种想在defer中篡改值的方法，就是具名返回值
// 这个改变的是返回值本身
func DeferRetureV1() (a int) {
	a = 0
	defer func() {
		a = 1
	}()
	return a
}

// 这种也能该变成功，这里改变的是指针指向的值 => 所以也能成功
func DeferReturnV2() *MyStruct {
	res := &MyStruct{
		name: "Tom",
	}
	defer func() {
		res.name = "Jerry"
	}()
	return res
}

type MyStruct struct {
	name string
}
